package top.lingchen.boot.config;

import ch.qos.logback.core.db.DBHelper;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
import top.lingchen.boot.bean.Car;
import top.lingchen.boot.bean.Pet;
import top.lingchen.boot.bean.User;

/**
 * @Author 凌宸
 * @create 2021-12-03 下午 4:12
 * @Description
 * @Version 1.0
 */

/**
 *  配置类中使用 @Bean 注解标注在方法上给容器注册组件，默认是单实例的
 *  配置类本身也是组件
 *  proxyBeanMethods:代理方法
 *      Full(proxyBeanMethods = true), 默认值，保证每个方法即使被调用多次，返回的都是同一个实例
 *      Lite(proxyBeanMethods = false),保证每个方法每次调用返回的都是新的实例
 *      若组件之间存在依赖关系，即组件依赖，则必须使用 Full 模式，其他默认使用 Lite 模式
 *  对于组件依赖的简单理解：
 *      比如下述中，若是 User 对象与 Pet 对象进行绑定，比如一个用户都有自己的宠物，那么久必须使用 Full 模式。
 *
 *  @Import({User.class, DBHelper.class})
 *      给容器中自动创建出上述类型的组件，默认的组件名称是全类名，调用的是相应类的空参构造器
 */
@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = true) // 告诉 SpringBoot 这是一个配置类 == 配置文件
@ConditionalOnMissingBean(name = "tom")
@ImportResource("classpath:beans.xml")

@EnableConfigurationProperties(Car.class)
/**
 * 开启 Car 类的配置绑定功能，将这个 Car组件自动注入到容器中
 */
public class MyConfig {

    @Bean // 给容器添加组件。以方法名作为组件的 id，返回值类型作为组件类型，返回的值就是组件在容器中的实例
//    @ConditionalOnBean(name = "tom")
    public User user01(){
        User zs = new User("张三", 21);
        zs.setPet(tomPet());
        return zs;
    }

    @Bean("tom2") // 以 "tom" 作为组件的 id
    public Pet tomPet(){
        return new Pet("tomcat");
    }
}
